
#pragma once

namespace atr {

/**
 * @brief Namespace only for internal use of atr library
 * @details Please don't use this namespace outside the atr library. IF you REALLY need to - do it with special care.
 */
namespace __ {

template <class Base, class Iterator, class ... Types> struct __erase;

    ////////////////////
    // Position

template <template <class ...> class Base, class ... Types,
          template <class, class> class Iterator, class ... Prevs,
                                                  class Next, class ... Nexts>
struct __erase<Base<Types...>, Iterator<Base<Prevs...>, Base<Next, Nexts...>>>
{
    static_assert(std::is_same<Base<Types...>,
                               Base<Prevs..., Next, Nexts...>>::value,
                  "<Position> iterator have to belong to proper container");
    using type = Base<Prevs..., Nexts...>;
};

template <template <class ...> class Base, class ... Types,
          template <class, class> class Iterator, class ... Prevs>
struct __erase<Base<Types...>, Iterator<Base<Prevs...>, Base<>> >
{
    static_assert(std::is_same<Base<Types...>,
                               Base<Prevs...>>::value,
                  "<Position> iterator have to belong to proper container");
    using type = Base<Prevs...>;
};

// TODO erase - first last

} // namespace __
} // namespace atr